<!--
 * @Author: Wushiqi
 * @Descripttion: promise和async/await的区别
 * @Date: 2021-05-20 09:19:46
 * @LastEditor: Wushiqi
 * @LastEditTime: 2021-05-21 21:34:22
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>promise和async/await的区别</title>
  <style>
    pre {
      background-color: #8080803a;
      border-radius: 5px;
      color: rgb(14, 109, 168);
      font-size: 16px;
      white-space: pre-wrap;
    }
    button {
      background-color: #ffffff;
      color: indianred;
      border: 1px solid;
      border-radius: 2px;
      padding: 5px;
      outline: thin;
    }
    button:hover {
      background-color: rgba(205, 92, 92, 0.397);
    }
  </style>
</head>
<body>
  <h2>区别：</h2>
  <ol>
    <li>async让代码更加简洁，不需要写匿名函数处理promise的resolve值，也不需要定义多余的data变量，可以避免嵌套代码。</li>
    <li>在错误处理方面，promise.then的错误在外部catch无法捕获到，需要两层catch；而async/await只需要一层就可以捕获到同步和异步的错误。</li>
    <li>在调试方面，async/await调试更加简单。promise调试，首先不能在返回表达式的箭头函数中设置断点，其次如果在.then代码块中设置断点，按StepOver(单步调试，将子函数作为一步)不会跳到下一个.then，因为它只会跳过异步代码。而async/await不需要那么多箭头函数，可以像调试同步代码一样跳过await语句。</li>
    <li>如果需要使用返回值，promise需要嵌套调用，async/await会更为直观。</li>
  </ol>
  <h3>1.错误捕捉：</h3>
  <h4>添加一个模拟请求的函数</h4>
  <pre>
    function getJson() {
      return new Promise((resolve, reject) => {
        resolve("{aa: 111201}")
      })
    }
  </pre>
  <h3>用promise的情况：</h3>
  <button onclick="makeRequest1()">只有外部catch</button>
  <h4>点击按钮查看控制台，可以发现直接报错了，外部的catch并没有拦截到错误</h4>
  <pre>
    const makeRequest1 = () => {
      try {
        getJson().then(res => {
          console.log(res);
          const data = JSON.parse(res)
          console.log('data', data);
        })
      } catch (error) {
        console.log('outer catch= ' + error);
      }
    }
  </pre>
  <button onclick="makeRequest2()">有内部catch</button>
  <h4>点击按钮可以看见内部的catch捕获到错误了</h4>
  <pre>
    const makeRequest2 = () => {
      try {
        getJson().then(res => {
          console.log(res);
          const data = JSON.parse(res)
          console.log('data', data);
        })
        .catch(err => {
          console.log('inter catch= ' + err);
        })
      } catch (error) {
        console.log('outer catch= ' + error);
      }
    }
  </pre>
  <h3>用async/await的情况：</h3>
  <button onclick="makeRequest3()">async只有一个catch</button>
  <h4>报错被直接拦截到了：</h4>
  <pre>
    async function makeRequest3() {
      try {
        await getJson().then(res => {
          console.log(res);
          const data = JSON.parse(res)
          console.log(data);
        })
      } catch (error) {
        console.log('async catch= ' + error);
      }
    }
  </pre>
  <p>
    * 由此可以看出，在promise.then中出现错误的话，外层的try/caych是无法捕获到的，需要在内部加一层catch，会显得比较冗余；而是用async/await的话，只需要一个try/catch就可以捕获到同步和异步的错误，代码更加简洁。
  </p>
  <h3>2.使用返回值</h3>
  <button onclick="makeRequest4()">嵌套promise</button>
  <pre>
    function makeRequest4() {
      return promise1().then(res1 => {
        return promise2().then(res2 => {
          return promise3(res1, res2).then(res3 => {
            console.log(res3);
          })
        })
      })
    }
  </pre>
  <button onclick="makeRequest5()">async/await使用返回值</button>
  <pre>
    async function makeRequest5() {
      const res1 = await promise1()
      const res2 = await promise2()
      const res3 = await promise3(res1, res2)
      console.log(res3);
    }
  </pre>
  <p>* 由此可见，await的写法更加简洁直观</p>
  <script>
    function getJson() {
      return new Promise((resolve, reject) => {
        resolve("{aa: 111201}")
      })
    }
    const makeRequest1 = () => {
      try {
        getJson().then(res => {
          console.log(res);
          const data = JSON.parse(res)
          console.log('data', data);
        })
        // .catch(err => {
        //   console.log('inter catch= ' + err);
        // })
      } catch (error) {
        console.log('outer catch= ' + error);
      }
    }
    const makeRequest2 = () => {
      try {
        getJson().then(res => {
          console.log(res);
          const data = JSON.parse(res)
          console.log('data', data);
        })
        .catch(err => {
          console.log('inter catch= ' + err);
        })
      } catch (error) {
        console.log('outer catch= ' + error);
      }
    }
    async function makeRequest3() {
      try {
        await getJson().then(res => {
          console.log(res);
          const data = JSON.parse(res)
          console.log(data);
        })
      } catch (error) {
        console.log('async catch= ' + error);
      }
    }
  </script>
  <script>
    function promise1() {
      return new Promise((resolve, reject) => {
        resolve('promise1')
      })
    }
    function promise2(value) {
      return new Promise((resolve, reject) => {
        resolve('promise2')
      })
    }
    function promise3(value1, value2) {
      return new Promise((resolve, reject) => {
        resolve(`我拿到了前两个参数: ${ value1 }, ${ value2 }`)
      })
    }

    function makeRequest4() {
      return promise1().then(res1 => {
        return promise2().then(res2 => {
          return promise3(res1, res2).then(res3 => {
            console.log(res3);
          })
        })
      })
    }
    async function makeRequest5() {
      const res1 = await promise1()
      const res2 = await promise2()
      const res3 = await promise3(res1, res2)
      console.log(res3);
    }
  </script>
</body>
</html>